"""数据同步相关的模型

定义数据同步、冲突解决等相关的数据模型。
"""

import uuid
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth import get_user_model
from django.utils import timezone

User = get_user_model()


class SyncSession(models.Model):
    """同步会话模型
    
    记录每次同步操作的会话信息。
    """
    
    # 同步状态选择
    STATUS_CHOICES = [
        ('pending', _('等待中')),
        ('in_progress', _('进行中')),
        ('completed', _('已完成')),
        ('failed', _('失败')),
        ('cancelled', _('已取消')),
    ]
    
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
        verbose_name=_('会话ID')
    )
    
    # 用户
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='sync_sessions',
        verbose_name=_('用户')
    )
    
    # 同步信息
    status = models.CharField(
        _('同步状态'),
        max_length=20,
        choices=STATUS_CHOICES,
        default='pending',
        help_text=_('当前同步状态')
    )
    
    client_version = models.CharField(
        _('客户端版本'),
        max_length=50,
        blank=True,
        help_text=_('发起同步的客户端版本')
    )
    
    device_id = models.CharField(
        _('设备ID'),
        max_length=100,
        blank=True,
        help_text=_('发起同步的设备标识')
    )
    
    # 同步统计
    items_uploaded = models.PositiveIntegerField(
        _('上传项目数'),
        default=0,
        help_text=_('本次同步上传的项目数量')
    )
    
    items_downloaded = models.PositiveIntegerField(
        _('下载项目数'),
        default=0,
        help_text=_('本次同步下载的项目数量')
    )
    
    conflicts_detected = models.PositiveIntegerField(
        _('冲突数量'),
        default=0,
        help_text=_('检测到的冲突数量')
    )
    
    conflicts_resolved = models.PositiveIntegerField(
        _('已解决冲突'),
        default=0,
        help_text=_('已解决的冲突数量')
    )
    
    # 错误信息
    error_message = models.TextField(
        _('错误信息'),
        blank=True,
        help_text=_('同步失败时的错误信息')
    )
    
    # 时间字段
    started_at = models.DateTimeField(
        _('开始时间'),
        auto_now_add=True
    )
    
    completed_at = models.DateTimeField(
        _('完成时间'),
        null=True,
        blank=True,
        help_text=_('同步完成的时间')
    )
    
    class Meta:
        verbose_name = _('同步会话')
        verbose_name_plural = _('同步会话')
        db_table = 'sync_session'
        ordering = ['-started_at']
        indexes = [
            models.Index(fields=['user', '-started_at']),
            models.Index(fields=['status', '-started_at']),
        ]
    
    def __str__(self):
        """返回同步会话的字符串表示"""
        return f"{self.user.email} - {self.status} - {self.started_at}"
    
    def mark_completed(self):
        """标记同步完成"""
        self.status = 'completed'
        self.completed_at = timezone.now()
        self.save(update_fields=['status', 'completed_at'])
    
    def mark_failed(self, error_message):
        """标记同步失败"""
        self.status = 'failed'
        self.error_message = error_message
        self.completed_at = timezone.now()
        self.save(update_fields=['status', 'error_message', 'completed_at'])
    
    @property
    def duration(self):
        """获取同步持续时间"""
        if self.completed_at:
            return self.completed_at - self.started_at
        return timezone.now() - self.started_at


class SyncItem(models.Model):
    """同步项目模型
    
    记录每个同步项目的详细信息。
    """
    
    # 项目类型选择
    ITEM_TYPE_CHOICES = [
        ('note', _('笔记')),
        ('category', _('分类')),
        ('tag', _('标签')),
        ('attachment', _('附件')),
    ]
    
    # 操作类型选择
    ACTION_CHOICES = [
        ('create', _('创建')),
        ('update', _('更新')),
        ('delete', _('删除')),
    ]
    
    # 同步状态选择
    STATUS_CHOICES = [
        ('pending', _('等待中')),
        ('synced', _('已同步')),
        ('conflict', _('冲突')),
        ('error', _('错误')),
    ]
    
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
        verbose_name=_('项目ID')
    )
    
    # 关联同步会话
    session = models.ForeignKey(
        SyncSession,
        on_delete=models.CASCADE,
        related_name='items',
        verbose_name=_('同步会话')
    )
    
    # 项目信息
    item_type = models.CharField(
        _('项目类型'),
        max_length=20,
        choices=ITEM_TYPE_CHOICES,
        help_text=_('同步项目的类型')
    )
    
    item_id = models.CharField(
        _('项目ID'),
        max_length=100,
        help_text=_('项目的唯一标识符')
    )
    
    action = models.CharField(
        _('操作类型'),
        max_length=20,
        choices=ACTION_CHOICES,
        help_text=_('对项目执行的操作')
    )
    
    status = models.CharField(
        _('同步状态'),
        max_length=20,
        choices=STATUS_CHOICES,
        default='pending',
        help_text=_('项目的同步状态')
    )
    
    # 数据内容
    client_data = models.JSONField(
        _('客户端数据'),
        null=True,
        blank=True,
        help_text=_('客户端提交的数据')
    )
    
    server_data = models.JSONField(
        _('服务器数据'),
        null=True,
        blank=True,
        help_text=_('服务器端的数据')
    )
    
    # 版本信息
    client_version = models.PositiveIntegerField(
        _('客户端版本'),
        default=1,
        help_text=_('客户端数据的版本号')
    )
    
    server_version = models.PositiveIntegerField(
        _('服务器版本'),
        default=1,
        help_text=_('服务器数据的版本号')
    )
    
    # 时间戳
    client_timestamp = models.DateTimeField(
        _('客户端时间戳'),
        null=True,
        blank=True,
        help_text=_('客户端数据的最后修改时间')
    )
    
    server_timestamp = models.DateTimeField(
        _('服务器时间戳'),
        null=True,
        blank=True,
        help_text=_('服务器数据的最后修改时间')
    )
    
    # 错误信息
    error_message = models.TextField(
        _('错误信息'),
        blank=True,
        help_text=_('同步失败时的错误信息')
    )
    
    # 时间字段
    created_at = models.DateTimeField(
        _('创建时间'),
        auto_now_add=True
    )
    
    updated_at = models.DateTimeField(
        _('更新时间'),
        auto_now=True
    )
    
    class Meta:
        verbose_name = _('同步项目')
        verbose_name_plural = _('同步项目')
        db_table = 'sync_item'
        ordering = ['-created_at']
        unique_together = [['session', 'item_type', 'item_id']]
        indexes = [
            models.Index(fields=['session', 'status']),
            models.Index(fields=['item_type', 'item_id']),
            models.Index(fields=['status', '-created_at']),
        ]
    
    def __str__(self):
        """返回同步项目的字符串表示"""
        return f"{self.item_type}:{self.item_id} - {self.action} - {self.status}"
    
    def mark_synced(self):
        """标记为已同步"""
        self.status = 'synced'
        self.save(update_fields=['status'])
    
    def mark_conflict(self, error_message=None):
        """标记为冲突"""
        self.status = 'conflict'
        if error_message:
            self.error_message = error_message
        self.save(update_fields=['status', 'error_message'])
    
    def mark_error(self, error_message):
        """标记为错误"""
        self.status = 'error'
        self.error_message = error_message
        self.save(update_fields=['status', 'error_message'])
    
    @property
    def has_conflict(self):
        """检查是否存在冲突"""
        return (
            self.client_timestamp and
            self.server_timestamp and
            self.client_timestamp != self.server_timestamp and
            self.client_version != self.server_version
        )


class ConflictResolution(models.Model):
    """冲突解决模型
    
    记录数据冲突的解决方案。
    """
    
    # 解决策略选择
    RESOLUTION_CHOICES = [
        ('client_wins', _('客户端优先')),
        ('server_wins', _('服务器优先')),
        ('merge', _('合并')),
        ('manual', _('手动解决')),
    ]
    
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
        verbose_name=_('解决方案ID')
    )
    
    # 关联同步项目
    sync_item = models.OneToOneField(
        SyncItem,
        on_delete=models.CASCADE,
        related_name='resolution',
        verbose_name=_('同步项目')
    )
    
    # 解决方案
    resolution_strategy = models.CharField(
        _('解决策略'),
        max_length=20,
        choices=RESOLUTION_CHOICES,
        help_text=_('冲突解决的策略')
    )
    
    # 解决后的数据
    resolved_data = models.JSONField(
        _('解决后数据'),
        help_text=_('冲突解决后的最终数据')
    )
    
    # 解决者
    resolved_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='resolved_conflicts',
        verbose_name=_('解决者')
    )
    
    # 解决说明
    resolution_notes = models.TextField(
        _('解决说明'),
        blank=True,
        help_text=_('冲突解决的说明信息')
    )
    
    # 时间字段
    resolved_at = models.DateTimeField(
        _('解决时间'),
        auto_now_add=True
    )
    
    class Meta:
        verbose_name = _('冲突解决')
        verbose_name_plural = _('冲突解决')
        db_table = 'conflict_resolution'
        ordering = ['-resolved_at']
        indexes = [
            models.Index(fields=['resolved_by', '-resolved_at']),
            models.Index(fields=['resolution_strategy', '-resolved_at']),
        ]
    
    def __str__(self):
        """返回冲突解决的字符串表示"""
        return f"{self.sync_item} - {self.resolution_strategy}"